#pragma once

/**
 * @file time_utils.h
 * @brief 时间相关工具函数
 * @details 提供高精度时间戳获取和时间格式化功能
 */

#include <string>
#include <chrono>
#include <ctime>

#include "perf_utils.h"

namespace Common {
  /**
   * @typedef Nanos
   * @brief 纳秒时间戳类型
   * @details 使用64位整数表示纳秒级时间戳
   */
  typedef int64_t Nanos;

  /**
   * @brief 时间单位转换常量
   * @{
   */
  /// @brief 纳秒到微秒的转换比例：1微秒 = 1000纳秒
  constexpr Nanos NANOS_TO_MICROS = 1000;
  /// @brief 微秒到毫秒的转换比例：1毫秒 = 1000微秒
  constexpr Nanos MICROS_TO_MILLIS = 1000;
  /// @brief 毫秒到秒的转换比例：1秒 = 1000毫秒
  constexpr Nanos MILLIS_TO_SECS = 1000;
  /// @brief 纳秒到毫秒的转换比例：1毫秒 = 1,000,000纳秒
  constexpr Nanos NANOS_TO_MILLIS = NANOS_TO_MICROS * MICROS_TO_MILLIS;
  /// @brief 纳秒到秒的转换比例：1秒 = 1,000,000,000纳秒
  constexpr Nanos NANOS_TO_SECS = NANOS_TO_MILLIS * MILLIS_TO_SECS;
  /** @} */

  /**
   * @brief 获取当前系统时间的纳秒级时间戳
   * 
   * @return 返回自Unix纪元（1970-01-01）以来的纳秒数
   */
  inline auto getCurrentNanos() noexcept {
    return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
  }

  /**
   * @brief 获取格式化的当前时间字符串
   * 
   * @warning 字符串格式化操作效率较低，不建议在性能敏感场景频繁调用
   * 
   * @param[out] time_str 用于存储格式化后时间字符串的指针
   * @return 格式化后的时间字符串引用，格式为"HH:MM:SS.nanoseconds"
   */
  inline auto& getCurrentTimeStr(std::string* time_str) {
    const auto clock = std::chrono::system_clock::now();
    const auto time = std::chrono::system_clock::to_time_t(clock);

    char nanos_str[24];
    sprintf(nanos_str, "%.8s.%09ld", ctime(&time) + 11, std::chrono::duration_cast<std::chrono::nanoseconds>(clock.time_since_epoch()).count() % NANOS_TO_SECS);
    time_str->assign(nanos_str);

    return *time_str;
  }
}
